package com.gitee.wsl.android.file

//package com.newki.choosefile.provider

import android.database.Cursor
import android.database.MatrixCursor
import android.database.MatrixCursor.RowBuilder
import android.os.CancellationSignal
import android.os.Environment
import android.os.ParcelFileDescriptor
import android.provider.DocumentsProvider
import com.gitee.wsl.android.ext.store.getAppUri
import com.gitee.wsl.jvm.ext.base.DateTimeExt.sampleDateTimeFormat
import com.gitee.wsl.jvm.ext.store.FileExt.getSubfolderNum
import com.gitee.wsl.jvm.ext.store.formatFileSize

import java.io.File
import java.io.FileNotFoundException
import java.util.Date

/**
 * 选择文件
 *  <provider
 *     android:name=".provider.ChooseFileDocumentProvider"
 *     android:authorities="com.newki.choosefile.authorities"
 *     android:exported="true"
 *     android:grantUriPermissions="true"
 *     android:permission="android.permission.MANAGE_DOCUMENTS">
 *
 *     <intent-filter>
 *          <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
 *     </intent-filter>
 *
 *  </provider>
 *
 */
class ChooseFileDocumentProvider : DocumentsProvider() {
    @Throws(FileNotFoundException::class)
    override fun queryRoots(projection: Array<String>): Cursor? {
        return null
    }

    override fun isChildDocument(parentDocumentId: String, documentId: String): Boolean {
        return documentId.startsWith(parentDocumentId)
    }

    @Throws(FileNotFoundException::class)
    override fun queryDocument(documentId: String, projection: Array<String>): Cursor {

        // 创建一个查询cursor, 来设置需要查询的项, 如果"projection"为空, 那么使用默认项
        val result = MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION)
        includeFile(result, File(documentId), isRoot = false, isTop = false)
        return result
    }

    @Throws(FileNotFoundException::class)
    override fun queryChildDocuments(
        parentDocumentId: String,
        projection: Array<String>?,
        sortOrder: String
    ): Cursor {

        // 创建一个查询cursor, 来设置需要查询的项, 如果"projection"为空, 那么使用默认项。
        val result = MatrixCursor(projection ?: DEFAULT_DOCUMENT_PROJECTION)
        val parent = File(parentDocumentId)
        val isDirectory = parent.isDirectory
        val canRead = parent.canRead()
        val files = parent.listFiles()
        val isRoot = parent.absolutePath == Environment.getExternalStorageDirectory().absolutePath
        includeFile(result, parent, isRoot, true)

        //遍历添加处理文件列表
        if (isDirectory && canRead &&  files?.size!! > 0) {
            for (file in files) {
                // 添加文件的名字, 类型, 大小等属性
                includeFile(result, file, isRoot, false)
            }
        }
        return result
    }

    private fun includeFile(result: MatrixCursor, file: File, isRoot: Boolean, isTop: Boolean) {
        val row = result.newRow()
        row.add("isTop", if (isTop) "1" else "0")
        row.add("isRoot", if (isRoot) "1" else "0")
        if (file.isDirectory) {
            row.add("fileName", file.name)
            row.add("isDir", 1)
            row.add("fileSize", "共" + getSubfolderNum(file.absolutePath) + "项")
            row.add("fileLastUpdateTime", sampleDateTimeFormat.format(Date(file.lastModified())))
            row.add("filePath", file.absolutePath)
            row.add("filePathUri", file.absolutePath)
            row.add("fileType", FILE_TYPE_FOLDER)
            //row.add("fileTypeIconRes", R.drawable.file_folder)
        } else {
            row.add("fileName", file.name)
            row.add("isDir", 0)
            row.add("fileSize",file.formatFileSize)
            row.add("fileLastUpdateTime", sampleDateTimeFormat.format(Date(file.lastModified())))
            row.add("filePath", file.absolutePath)
            row.add("filePathUri", file.getAppUri().toString())
            setFileType(row, file.absolutePath)
        }
    }

    private fun setFileType(row: RowBuilder, absolutePath: String) {
        /*if (FileUtil.isAudioFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_AUDIO)
            row.add("fileTypeIconRes", R.drawable.file_audio)
        } else if (FileUtil.isImageFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_IMAGE)
            row.add("fileTypeIconRes", R.drawable.file_image)
        } else if (FileUtil.isVideoFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_VIDEO)
            row.add("fileTypeIconRes", R.drawable.file_video)
        } else if (FileUtil.isTextFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_TEXT)
            row.add("fileTypeIconRes", R.drawable.file_text)
        } else if (FileUtil.isXLSFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_XLS)
            row.add("fileTypeIconRes", R.drawable.file_excel)
        } else if (FileUtil.isPPTFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_PPT)
            row.add("fileTypeIconRes", R.drawable.file_ppt)
        } else if (FileUtil.isPDFFileType(absolutePath)) {
            row.add("fileType", ChooseFile.FILE_TYPE_PDF)
            row.add("fileTypeIconRes", R.drawable.file_pdf)
        } else {
            row.add("fileType", ChooseFile.FILE_TYPE_Unknown)
            row.add("fileTypeIconRes", R.drawable.file_unknown)
        }*/
    }

    @Throws(FileNotFoundException::class)
    override fun getDocumentType(documentId: String): String? {
        return null
    }

    @Throws(FileNotFoundException::class)
    override fun openDocument(
        documentId: String,
        mode: String,
        signal: CancellationSignal?
    ): ParcelFileDescriptor? {
        return null
    }

    override fun onCreate(): Boolean {
        return true
    }

    /*private fun getFileUri(context: Context, file: File): Uri {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            ChooseFileProvider.getUriForFile(context, "com.newki.choosefile.file.path.share", file)
        } else {
            Uri.fromFile(file)
        }
    }*/

    companion object {
        //文件类型
        const val FILE_TYPE_FOLDER = "Folder"

        private val DEFAULT_DOCUMENT_PROJECTION = arrayOf(
            "isTop", "isRoot", "fileName", "isDir", "fileSize", "fileLastUpdateTime",
            "filePath", "filePathUri", "fileType", "fileTypeIconRes"
        )
    }
}